﻿using System;
using System.Collections.Generic;
using System.Reflection;
using TestMonkey.Models;
using System.Diagnostics.CodeAnalysis;

namespace TestMonkey.TestRunners
{
	public abstract class TestRunner
	{
		public abstract CodeString TestClassAttribute { get; }
		public abstract CodeString TestAttribute { get; }
		public abstract CodeString ManualTestAttribute { get; }
		public abstract CodeString Imports { get; }

		public virtual CodeString TagAttributes(params string[] tags)
		{
			return TagAttributes((IList<String>)tags);
		}
		public virtual CodeString TagAttributes(IList<string> tags)
		{
			return "";
		}

		public abstract CodeString IsTrue(string actual);
		public abstract CodeString IsTrue(string actual, string message);

		public abstract CodeString IsFalse(string actual);
		public abstract CodeString IsFalse(string actual, string message);

		public abstract CodeString IsNull(string actual);
		public abstract CodeString IsNull(string actual, string message);

		public abstract CodeString AreEqual(string expected, string actual);
		public abstract CodeString AreEqual(string expected, string actual, string message);
		public abstract CodeString Inconclusive(string message);
		public abstract CodeString Fail(string message);

		public CodeString AreEqual(ClassModel type, string expected, string actual)
		{
			if (type == null)
				throw new ArgumentNullException("type", "type is null.");
			if (String.IsNullOrEmpty(expected))
				throw new ArgumentException("expected is null or empty.", "expected");
			if (String.IsNullOrEmpty(actual))
				throw new ArgumentException("actual is null or empty.", "actual");

			if (type.Type == typeof(string))
			{
				return IsTrue(string.Format("(string.IsNullOrEmpty({0}) && string.IsNullOrEmpty({1})) || {0} == {1}", expected, actual));
			}

			return AreEqual(expected, actual);
		}

		public CodeString AreEqual(ClassModel type, string expected, string actual, string message)
		{
			if (type == null)
				throw new ArgumentNullException("type", "type is null.");
			if (String.IsNullOrEmpty(expected))
				throw new ArgumentException("expected is null or empty.", "expected");
			if (String.IsNullOrEmpty(actual))
				throw new ArgumentException("actual is null or empty.", "actual");

			if (type.Type == typeof(string))
			{
				return IsTrue(string.Format("(string.IsNullOrEmpty({0}) && string.IsNullOrEmpty({1})) || {0} == {1}", expected, actual), message);
			}

			return AreEqual(expected, actual, message);
		}

		public virtual CodeString TestBaseClass
		{
			get { return ""; }
		}

		[SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
		public CodeString GeneratedCodeAttribute
		{
			get { return string.Format(@"[GeneratedCode(""TestMonkey"", ""{0}"")]", Assembly.GetExecutingAssembly().GetName().Version); }
		}


	}
}
